package org.example.security.util;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class CaptchaUtils {


    /**
     * 生成字符验证码，并响应到浏览器
     */
    public static String drawCharCaptcha(HttpServletResponse response){
        responseWrapper(response);
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            builder.append(randomChar());
        }
        String code = builder.toString();

        //定义图片的宽度和高度
        int width = 120;
        int height = 25;
        //建立bufferedImage对象，制定图片的长度和宽度以及色彩
        BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
        //获取Graphics2D,开始绘制验证码
        Graphics2D g = bi.createGraphics();
        Font font = new Font("微软雅黑",Font.PLAIN,20);
        Color color = new Color(255, 255, 255);
        g.setFont(font);
        g.setColor(color);
        g.setBackground(new Color(41,214,204));
        g.clearRect(0,0,width,height);
        //绘制形状
        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds= font.getStringBounds(code,context);
        //计算文字的坐标和间距
        double x = (width - bounds.getWidth())/2;
        double y = (height - bounds.getHeight())/2;
        double ascent = bounds.getY();
        double baseY = y -ascent;
        g.drawString(code,(int)x,(int)baseY);
        //结束绘制
        g.dispose();
        // 响应图片
        try {
            ImageIO.write(bi,"jpg",response.getOutputStream());
            //刷新响应流
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return code;
    }

    /**
     * 算术表达式验证码
     * 干扰线的产生
     * 范围随机颜色、随机数
     * @param response
     * @return
     */
    public static String drawAlgExpCaptcha(HttpServletResponse response){
        responseWrapper(response);
        int width = 100;
        int height = 30;
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        Random random = new Random();
        g.setColor(getRandomColor(240,250));
        g.setFont(new Font("微软雅黑",Font.PLAIN,22));
        g.fillRect(0,0,width,height);

        //干扰线的绘制：绘制线条到图片中
        g.setColor(getRandomColor(180,230));
        for (int i = 0; i < 100; i++) {
            int x= random.nextInt(width);
            int y= random.nextInt(height);
            int x1 = random.nextInt(60);
            int y1 = random.nextInt(60);
            g.drawLine(x,y,x1,y1);
        }

        //算术表达式的拼接
        int num1= (int) (Math.random()*10+1);
        int num2= (int) (Math.random()*10+1);
        int fuhao = random.nextInt(4);//产生一个[0,3]之间的随机整数
        String fuhaostr = null;
        int result =0;
        switch (fuhao){
            case 0:
                fuhaostr = "+";
                result=num1+num2;
                break;
            case 1:
                fuhaostr = "-";
                result=num1-num2;
                break;
            case 2:
                fuhaostr = "*";
                result=num1*num2;
                break;
            case 3:
                fuhaostr = "/";
                result=num1/num2;
                break;
        }

        String calc = num1+" "+fuhaostr+" "+num2 + " = ?";
        g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
        g.drawString(calc,5,25);
        g.dispose();

        try {
            ImageIO.write(image,"JPEG",response.getOutputStream());
            response.flushBuffer();
            return String.valueOf(result);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 范围随机颜色
     * @param fc
     * @param bc
     * @return
     */
    private static Color getRandomColor(int fc, int bc){
        Random random = new Random();
        //随机颜色，了解颜色Color(red,green,blue),rgb3元色 0 - 255
        if (fc > 255) {
            fc = 255;
        }

        if (bc > 255) {
            bc = 255;
        }
        int r = fc+random.nextInt(bc-fc);
        int g = fc+random.nextInt(bc-fc);
        int b = fc+random.nextInt(bc-fc);
        return new Color(r,g,b);

    }

    /**
     * 产生随机数字和字母
     * @return
     */
    private static char randomChar(){
        //定义验证需要的字母和数字
        String str  = "abcdefghijkmlnopqrstuvwxyzABCDEFGHIJKMLNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        return str.charAt(random.nextInt(str.length()));
    }

    /**
     * 包装响应头
     */
    private static void responseWrapper(HttpServletResponse response) {
        // 禁用浏览器缓存
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, mustrevalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // 定义response输出类型为image/jpeg类型
        response.setContentType("image/jpeg");
    }
}
